home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PAS_0793 / UNIXDATE.PAS < prev    next >
Pascal/Delphi Source File  |  1993-08-01  |  9KB  |  248 lines

  1. {─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
  2. Msg  : 447 of 448
  3. From : Brian Stark                         1:324/275.0          14 Jul 93  21:36
  4. To   : Chad Thevis
  5. Subj : UNIX-STYLE TIMESTAMP
  6. ────────────────────────────────────────────────────────────────────────────────}
  7. Unit UnixDate;
  8. (***************************************************************************)
  9. (* UNIX DATE Version 1.01                                                  *)
  10. (* This unit provides access to UNIX date related functions and procedures *)
  11. (* A UNIX date is the number of seconds from January 1, 1970. This unit    *)
  12. (* may be freely used. If you modify the source code, please do not        *)
  13. (* distribute your enhancements.                                           *)
  14. (* (C) 1991-1993 by Brian Stark.                                           *)
  15. (* This is a programming release from Digital Illusions                    *)
  16. (* FidoNet 1:289/27.2 + Columbia, MO - USA                                 *)
  17. (* Revision History                                                        *)
  18. (* ----------------------------------------------------------------------- *)
  19. (* 06-13-1993 1.02 | Minor code cleanup                                    *)
  20. (* 05-23-1993 1.01 | Added a few more routines for use with ViSiON BBS     *)
  21. (* ??-??-1991 1.00 | First release                                         *)
  22. (* ----------------------------------------------------------------------- *)
  23. (***************************************************************************)
  24.  
  25. INTERFACE
  26.  
  27. Uses
  28.    DOS;
  29.  
  30. Function  GetTimeZone : ShortInt;
  31.   {Returns the value from the enviroment variable "TZ". If not found, UTC is
  32.    assumed, and a value of zero is returned}
  33. Function  IsLeapYear(Source : Word) : Boolean;
  34.   {Determines if the year is a leap year or not}
  35. Function  Norm2Unix(Y, M, D, H, Min, S : Word) : LongInt;
  36.   {Convert a normal date to its UNIX date. If environment variable "TZ" is
  37.    defined, then the input parameters are assumed to be in **LOCAL TIME**}
  38. Procedure Unix2Norm(Date : LongInt; Var Y, M, D, H, Min, S : Word);
  39.   {Convert a UNIX date to its normal date counterpart. If the environment
  40.    variable "TZ" is defined, then the output will be in **LOCAL TIME**}
  41.  
  42. Function  TodayInUnix : LongInt;
  43.   {Gets today's date, and calls Norm2Unix}
  44. {
  45.  Following returns a string and requires the TechnoJock totSTR unit.
  46. Function  Unix2Str(N : LongInt) : String;
  47. }
  48. Const
  49.   DaysPerMonth :
  50.     Array[1..12] of ShortInt =
  51. (031,028,031,030,031,030,031,031,030,031,030,031);
  52.   DaysPerYear  :
  53.     Array[1..12] of Integer  =
  54. (031,059,090,120,151,181,212,243,273,304,334,365);
  55.   DaysPerLeapYear :
  56.     Array[1..12] of Integer  =
  57. (031,060,091,121,152,182,213,244,274,305,335,366);
  58.   SecsPerYear      : LongInt  = 31536000;
  59.   SecsPerLeapYear  : LongInt  = 31622400;
  60.   SecsPerDay       : LongInt  = 86400;
  61.   SecsPerHour      : Integer  = 3600;
  62.   SecsPerMinute    : ShortInt = 60;
  63.  
  64. IMPLEMENTATION
  65.  
  66. Function GetTimeZone : ShortInt;
  67. Var
  68.   Environment : String;
  69.   Index : Integer;
  70. Begin
  71.   GetTimeZone := 0;                            {Assume UTC}
  72.   Environment := GetEnv('TZ');       {Grab TZ string}
  73.   For Index := 1 To Length(Environment) Do
  74.     Environment[Index] := Upcase(Environment[Index]);
  75. (*
  76.   NOTE: I have yet to find a complete list of the ISO table of time zone
  77.         abbreviations. The following is excerpted from the Opus-Cbcs
  78.         documentation files.
  79. *)
  80.   If Environment =  'EST05'    Then GetTimeZone := -05; {USA EASTERN}
  81.   If Environment =  'EST05EDT' Then GetTimeZone := -06;
  82.   If Environment =  'CST06'    Then GetTimeZone := -06; {USA CENTRAL}
  83.   If Environment =  'CST06CDT' Then GetTimeZone := -07;
  84.   If Environment =  'MST07'    Then GetTimeZone := -07; {USA MOUNTAIN}
  85.   If Environment =  'MST07MDT' Then GetTimeZone := -08;
  86.   If Environment =  'PST08'    Then GetTimeZone := -08;
  87.   If Environment =  'PST08PDT' Then GetTimeZone := -09;
  88.   If Environment =  'YST09'    Then GetTimeZone := -09;
  89.   If Environment =  'AST10'    Then GetTimeZone := -10;
  90.   If Environment =  'BST11'    Then GetTimeZone := -11;
  91.   If Environment =  'CET-1'    Then GetTimeZone :=  01;
  92.   If Environment =  'CET-01'   Then GetTimeZone :=  01;
  93.   If Environment =  'EST-10'   Then GetTimeZone :=  10;
  94.   If Environment =  'WST-8'    Then GetTimeZone :=  08; {Perth, Western
  95. Austrailia}
  96.   If Environment =  'WST-08'   Then GetTimeZone :=  08;
  97. End;
  98.  
  99. Function IsLeapYear(Source : Word) : Boolean;
  100. Begin
  101. (*
  102.   NOTE: This is wrong!
  103. *)
  104.   If (Source Mod 4 = 0) Then
  105.     IsLeapYear := True
  106.   Else
  107.     IsLeapYear := False;
  108. End;
  109.  
  110. Function Norm2Unix(Y,M,D,H,Min,S : Word) : LongInt;
  111. Var
  112.   UnixDate : LongInt;
  113.   Index    : Word;
  114. Begin
  115.   UnixDate := 0;                                                 {initialize}
  116.   Inc(UnixDate,S);                                              {add seconds}
  117.   Inc(UnixDate,(SecsPerMinute * Min));                          {add minutes}
  118.   Inc(UnixDate,(SecsPerHour * H));                                {add hours}
  119.   (*************************************************************************)
  120.   (* If UTC = 0, and local time is -06 hours of UTC, then                  *)
  121.   (* UTC := UTC - (-06 * SecsPerHour)                                      *)
  122.   (* Remember that a negative # minus a negative # yields a positive value *)
  123.   (*************************************************************************)
  124.   UnixDate := UnixDate - (GetTimeZone * SecsPerHour);            {UTC offset}
  125.  
  126.   If D > 1 Then                                 {has one day already passed?}
  127.     Inc(UnixDate,(SecsPerDay * (D-1)));
  128.  
  129.   If IsLeapYear(Y) Then
  130.     DaysPerMonth[02] := 29
  131.   Else
  132.     DaysPerMonth[02] := 28;                             {Check for Feb. 29th}
  133.  
  134.   Index := 1;
  135.   If M > 1 Then For Index := 1 To (M-1) Do    {has one month already passed?}
  136.     Inc(UnixDate,(DaysPerMonth[Index] * SecsPerDay));
  137.  
  138.   While Y > 1970 Do
  139.   Begin
  140.     If IsLeapYear((Y-1)) Then
  141.       Inc(UnixDate,SecsPerLeapYear)
  142.     Else
  143.       Inc(UnixDate,SecsPerYear);
  144.     Dec(Y,1);
  145.   End;
  146.  
  147.   Norm2Unix := UnixDate;
  148. End;
  149.  
  150. Procedure Unix2Norm(Date : LongInt; Var Y, M, D, H, Min, S : Word);
  151. {}
  152. Var
  153.   LocalDate : LongInt;
  154.   Done      : Boolean;
  155.   X         : ShortInt;
  156.   TotDays   : Integer;
  157. Begin
  158.   Y   := 1970;
  159.   M   := 1;
  160.   D   := 1;
  161.   H   := 0;
  162.   Min := 0;
  163.   S   := 0;
  164.   LocalDate := Date + (GetTimeZone * SecsPerHour);         {Local time date}
  165.  (*************************************************************************)
  166.  (* Sweep out the years...                                                *)
  167.  (*************************************************************************)
  168.   Done := False;
  169.   While Not Done Do
  170.   Begin
  171.     If LocalDate >= SecsPerYear Then
  172.     Begin
  173.       Inc(Y,1);
  174.       Dec(LocalDate,SecsPerYear);
  175.     End
  176.     Else
  177.       Done := True;
  178.  
  179.     If (IsLeapYear(Y+1)) And (LocalDate >= SecsPerLeapYear) And
  180.        (Not Done) Then
  181.     Begin
  182.       Inc(Y,1);
  183.       Dec(LocalDate,SecsPerLeapYear);
  184.     End;
  185.   End;
  186.   (*************************************************************************)
  187.   M := 1;
  188.   D := 1;
  189.   Done := False;
  190.   TotDays := LocalDate Div SecsPerDay;
  191.   If IsLeapYear(Y) Then
  192.   Begin
  193.     DaysPerMonth[02] := 29;
  194.     X := 1;
  195.     Repeat
  196.       If (TotDays <= DaysPerLeapYear[x]) Then
  197.       Begin
  198.         M := X;
  199.         Done := True;
  200.         Dec(LocalDate,(TotDays * SecsPerDay));
  201.         D := DaysPerMonth[M]-(DaysPerLeapYear[M]-TotDays) + 1;
  202.       End
  203.       Else
  204.         Done := False;
  205.       Inc(X);
  206.     Until (Done) or (X > 12);
  207.   End
  208.   Else
  209.   Begin
  210.     DaysPerMonth[02] := 28;
  211.     X := 1;
  212.     Repeat
  213.       If (TotDays <= DaysPerYear[x]) Then
  214.       Begin
  215.         M := X;
  216.         Done := True;
  217.         Dec(LocalDate,(TotDays * SecsPerDay));
  218.         D := DaysPerMonth[M]-(DaysPerYear[M]-TotDays) + 1;
  219.       End
  220.       Else
  221.         Done := False;
  222.       Inc(X);
  223.     Until Done = True or (X > 12);
  224.   End;
  225.   H := LocalDate Div SecsPerHour;
  226.     Dec(LocalDate,(H * SecsPerHour));
  227.   Min := LocalDate Div SecsPerMinute;
  228.     Dec(LocalDate,(Min * SecsPerMinute));
  229.   S := LocalDate;
  230. End;
  231.  
  232. Function  TodayInUnix : LongInt;
  233. Var
  234.   Year, Month, Day, DayOfWeek: Word;
  235.   Hour, Minute, Second, Sec100: Word;
  236. Begin
  237.   GetDate(Year, Month, Day, DayOfWeek);
  238.   GetTime(Hour, Minute, Second, Sec100);
  239.   TodayInUnix := Norm2Unix(Year,Month,Day,Hour,Minute,Second);
  240. End;
  241.  
  242. Function  Unix2Str(N : LongInt) : String;
  243. Var
  244.   Year, Month, Day, DayOfWeek  : Word;
  245.   Hour, Minute, Second, Sec100 : Word;
  246.   T : String;
  247. Begin
  248.   Unix2Norm(N, Year, Month, Day